package com.example.backend.service;

import com.example.backend.domain.entity.*;
import com.example.backend.domain.enums.TicketPriority;
import com.example.backend.domain.enums.TicketStatus;
import com.example.backend.dto.AdvancedSearchRequest;
import com.example.backend.dto.AdvancedSearchResponse;
import com.example.backend.repository.*;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 高级搜索服务
 * 提供多条件搜索、全文检索、搜索条件保存等功能
 */
@Service
@Transactional
public class AdvancedSearchService {

    @Autowired
    private TicketRepository ticketRepository;

    @Autowired
    private SavedSearchConditionRepository savedSearchRepository;

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private CommentRepository commentRepository;


    private final ObjectMapper objectMapper = new ObjectMapper();

    /**
     * 执行高级搜索
     */
    public AdvancedSearchResponse searchTickets(AdvancedSearchRequest request) {
        long startTime = System.currentTimeMillis();

        try {
            // 构建查询条件
            Pageable pageable = buildPageable(request);
            
            // 执行搜索
            Page<Ticket> ticketPage = executeAdvancedSearch(request, pageable);
            
            // 构建响应
            AdvancedSearchResponse response = buildSearchResponse(ticketPage, request);
            
            // 添加搜索元数据
            long searchTime = System.currentTimeMillis() - startTime;
            response.getMetadata().setSearchTimeMs(searchTime);
            response.getMetadata().setSearchQuery(buildSearchQuery(request));
            
            return response;
            
        } catch (Exception e) {
            throw new RuntimeException("高级搜索执行失败: " + e.getMessage(), e);
        }
    }

    /**
     * 构建分页和排序
     */
    private Pageable buildPageable(AdvancedSearchRequest request) {
        int page = request.getPage() != null ? request.getPage() : 0;
        int size = request.getSize() != null ? request.getSize() : 20;
        
        Sort sort = Sort.by(Sort.Direction.DESC, "updatedAt");
        if (request.getSortBy() != null) {
            Sort.Direction direction = "ASC".equalsIgnoreCase(request.getSortDirection()) ? 
                Sort.Direction.ASC : Sort.Direction.DESC;
            sort = Sort.by(direction, request.getSortBy());
        }
        
        return PageRequest.of(page, size, sort);
    }

    /**
     * 执行高级搜索
     */
    private Page<Ticket> executeAdvancedSearch(AdvancedSearchRequest request, Pageable pageable) {
        // 这里使用现有的搜索方法，实际项目中可以使用Criteria API或QueryDSL
        // 进行更复杂的动态查询构建
        
        if (request.getFullTextSearch() != null && !request.getFullTextSearch().trim().isEmpty()) {
            return executeFullTextSearch(request, pageable);
        } else {
            return executeConditionalSearch(request, pageable);
        }
    }

    /**
     * 执行全文检索
     */
    private Page<Ticket> executeFullTextSearch(AdvancedSearchRequest request, Pageable pageable) {
        String keyword = request.getFullTextSearch();
        
        // 使用现有的搜索方法，可以扩展为更复杂的全文检索
        return ticketRepository.searchTickets(
            keyword,
            request.getStatuses() != null && !request.getStatuses().isEmpty() ? 
                request.getStatuses().get(0).name() : null,
            request.getPriorities() != null && !request.getPriorities().isEmpty() ? 
                request.getPriorities().get(0).name() : null,
            request.getAssignedToIds() != null && !request.getAssignedToIds().isEmpty() ? 
                request.getAssignedToIds().get(0) : null,
            pageable
        );
    }

    /**
     * 执行条件搜索
     */
    private Page<Ticket> executeConditionalSearch(AdvancedSearchRequest request, Pageable pageable) {
        // 这里可以构建更复杂的查询条件
        // 暂时使用简单的条件查询
        
        TicketStatus status = request.getStatuses() != null && !request.getStatuses().isEmpty() ? 
            request.getStatuses().get(0) : null;
        TicketPriority priority = request.getPriorities() != null && !request.getPriorities().isEmpty() ? 
            request.getPriorities().get(0) : null;
        Long assignedToId = request.getAssignedToIds() != null && !request.getAssignedToIds().isEmpty() ? 
            request.getAssignedToIds().get(0) : null;
        
        return ticketRepository.searchTickets(
            request.getKeyword(),
            status != null ? status.name() : null,
            priority != null ? priority.name() : null,
            assignedToId,
            pageable
        );
    }

    /**
     * 构建搜索响应
     */
    private AdvancedSearchResponse buildSearchResponse(Page<Ticket> ticketPage, AdvancedSearchRequest request) {
        AdvancedSearchResponse response = new AdvancedSearchResponse();
        
        List<AdvancedSearchResponse.TicketSearchResult> results = ticketPage.getContent().stream()
            .map(this::convertToSearchResult)
            .collect(Collectors.toList());
        
        response.setTickets(results);
        response.setTotalElements(ticketPage.getTotalElements());
        response.setTotalPages(ticketPage.getTotalPages());
        response.setCurrentPage(ticketPage.getNumber());
        response.setPageSize(ticketPage.getSize());
        
        // 构建元数据
        AdvancedSearchResponse.SearchMetadata metadata = new AdvancedSearchResponse.SearchMetadata();
        metadata.setAppliedFilters(buildAppliedFilters(request));
        metadata.setFacetCounts(buildFacetCounts(request));
        metadata.setHasMoreResults(ticketPage.hasNext());
        response.setMetadata(metadata);
        
        return response;
    }

    /**
     * 转换为搜索结果
     */
    private AdvancedSearchResponse.TicketSearchResult convertToSearchResult(Ticket ticket) {
        AdvancedSearchResponse.TicketSearchResult result = new AdvancedSearchResponse.TicketSearchResult();
        
        result.setId(ticket.getId());
        result.setTicketNumber(ticket.getTicketNumber());
        result.setTitle(ticket.getTitle());
        result.setDescription(ticket.getDescription());
        result.setStatus(ticket.getStatus().name());
        result.setPriority(ticket.getPriority().name());
        result.setSource(ticket.getSource().name());
        
        if (ticket.getCategory() != null) {
            result.setCategoryName(ticket.getCategory().getCategoryName());
        }
        if (ticket.getCustomer() != null) {
            result.setCustomerName(ticket.getCustomer().getFullName());
        }
        if (ticket.getAssignedTo() != null) {
            result.setAssignedToName(ticket.getAssignedTo().getFullName());
        }
        if (ticket.getCreatedBy() != null) {
            result.setCreatedByName(ticket.getCreatedBy().getFullName());
        }
        
        result.setCreatedAt(ticket.getCreatedAt());
        result.setUpdatedAt(ticket.getUpdatedAt());
        result.setDueDate(ticket.getDueDate());
        result.setResolvedAt(ticket.getResolvedAt());
        result.setClosedAt(ticket.getClosedAt());
        result.setSatisfactionScore(ticket.getSatisfactionScore());
        result.setEstimatedHours(ticket.getEstimatedHours() != null ? ticket.getEstimatedHours().doubleValue() : null);
        result.setActualHours(ticket.getActualHours() != null ? ticket.getActualHours().doubleValue() : null);
        result.setIsPublic(ticket.getIsPublic());
        result.setIsEscalated(ticket.getIsEscalated());
        
        // 统计评论和附件数量
        result.setCommentCount(commentRepository.countByTicketId(ticket.getId()));
        // result.setAttachmentCount(attachmentRepository.countByTicketId(ticket.getId()));
        
        return result;
    }

    /**
     * 构建应用的过滤器
     */
    private List<String> buildAppliedFilters(AdvancedSearchRequest request) {
        List<String> filters = new ArrayList<>();
        
        if (request.getKeyword() != null) {
            filters.add("关键词: " + request.getKeyword());
        }
        if (request.getStatuses() != null && !request.getStatuses().isEmpty()) {
            filters.add("状态: " + request.getStatuses().stream().map(Enum::name).collect(Collectors.joining(", ")));
        }
        if (request.getPriorities() != null && !request.getPriorities().isEmpty()) {
            filters.add("优先级: " + request.getPriorities().stream().map(Enum::name).collect(Collectors.joining(", ")));
        }
        if (request.getCreatedStartDate() != null) {
            filters.add("创建时间: " + request.getCreatedStartDate() + " 至 " + request.getCreatedEndDate());
        }
        
        return filters;
    }

    /**
     * 构建分面计数
     */
    private Map<String, Long> buildFacetCounts(AdvancedSearchRequest request) {
        Map<String, Long> facetCounts = new HashMap<>();
        
        // 这里可以添加各种分面统计
        facetCounts.put("total", ticketRepository.count());
        facetCounts.put("open", ticketRepository.countByStatus(TicketStatus.OPEN));
        facetCounts.put("inProgress", ticketRepository.countByStatus(TicketStatus.IN_PROGRESS));
        facetCounts.put("resolved", ticketRepository.countByStatus(TicketStatus.RESOLVED));
        facetCounts.put("closed", ticketRepository.countByStatus(TicketStatus.CLOSED));
        
        return facetCounts;
    }

    /**
     * 构建搜索查询字符串
     */
    private String buildSearchQuery(AdvancedSearchRequest request) {
        StringBuilder query = new StringBuilder();
        
        if (request.getKeyword() != null) {
            query.append("关键词: ").append(request.getKeyword()).append(" ");
        }
        if (request.getFullTextSearch() != null) {
            query.append("全文: ").append(request.getFullTextSearch()).append(" ");
        }
        
        return query.toString().trim();
    }

    // ==================== 搜索条件保存功能 ====================

    /**
     * 保存搜索条件
     */
    public SavedSearchCondition saveSearchCondition(AdvancedSearchRequest request, Long userId) {
        try {
            Optional<User> userOpt = userRepository.findById(userId);
            if (userOpt.isEmpty()) {
                throw new RuntimeException("用户不存在");
            }
            
            SavedSearchCondition savedSearch = SavedSearchCondition.builder()
                .searchName(request.getSaveAsName())
                .searchDescription(request.getSaveDescription())
                .user(userOpt.get())
                .searchConditions(objectMapper.writeValueAsString(request))
                .isPublic(request.getIsPublicSave() != null ? request.getIsPublicSave() : false)
                .build();
            
            return savedSearchRepository.save(savedSearch);
        } catch (Exception e) {
            throw new RuntimeException("保存搜索条件失败: " + e.getMessage(), e);
        }
    }

    /**
     * 获取用户的保存搜索条件
     */
    public List<SavedSearchCondition> getUserSavedSearches(Long userId) {
        return savedSearchRepository.findByUserIdOrderByLastUsedAtDesc(userId, 
            PageRequest.of(0, 50)).getContent();
    }

    /**
     * 获取公开的搜索条件
     */
    public List<SavedSearchCondition> getPublicSavedSearches() {
        return savedSearchRepository.findByIsPublicTrueOrderByUsageCountDesc(
            PageRequest.of(0, 20)).getContent();
    }

    /**
     * 使用保存的搜索条件
     */
    public AdvancedSearchRequest loadSavedSearch(Long searchId) {
        Optional<SavedSearchCondition> searchOpt = savedSearchRepository.findById(searchId);
        if (searchOpt.isEmpty()) {
            throw new RuntimeException("保存的搜索条件不存在");
        }
        
        SavedSearchCondition savedSearch = searchOpt.get();
        
        // 更新使用次数
        savedSearchRepository.incrementUsageCount(searchId);
        
        try {
            return objectMapper.readValue(savedSearch.getSearchConditions(), AdvancedSearchRequest.class);
        } catch (Exception e) {
            throw new RuntimeException("加载搜索条件失败: " + e.getMessage());
        }
    }

    /**
     * 删除保存的搜索条件
     */
    public void deleteSavedSearch(Long searchId, Long userId) {
        savedSearchRepository.deleteByUserIdAndId(userId, searchId);
    }

    /**
     * 获取搜索建议
     */
    public List<String> getSearchSuggestions(String query, Long userId) {
        List<String> suggestions = new ArrayList<>();
        
        // 基于历史搜索提供建议
        List<SavedSearchCondition> recentSearches = savedSearchRepository.findRecentSearchConditions(userId, 
            PageRequest.of(0, 10));
        
        for (SavedSearchCondition search : recentSearches) {
            if (search.getSearchName().toLowerCase().contains(query.toLowerCase())) {
                suggestions.add(search.getSearchName());
            }
        }
        
        // 基于工单标题提供建议
        Page<Ticket> ticketPage = ticketRepository.searchTickets(query, null, null, null, 
            org.springframework.data.domain.PageRequest.of(0, 10));
        List<Ticket> tickets = ticketPage.getContent();
        for (Ticket ticket : tickets) {
            suggestions.add(ticket.getTitle());
        }
        
        return suggestions.stream().distinct().limit(10).collect(Collectors.toList());
    }

    /**
     * 获取热门搜索
     */
    public List<String> getPopularSearches() {
        List<SavedSearchCondition> popularSearches = savedSearchRepository.findPopularSearchConditions(
            PageRequest.of(0, 10));
        
        return popularSearches.stream()
            .map(SavedSearchCondition::getSearchName)
            .collect(Collectors.toList());
    }
}
